# -*- coding: utf-8 -*- 
# @project : 《Atcoder》
# @Author : created by bensonrachel on 2021/9/1
# @File : E - Third Avenue(BFS+多传送门搜索）.py

from collections import deque#双端队列，好用

INF = 0xffffffff
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
# 上下左右位置
vis = [0] * 26  # 传送门广场是否被访问过。


def markdown():#记录函数
    Sx = 0
    Sy = 0
    Gx = 0
    Gy = 0  # S、G的坐标
    for i in range(h):
        for j in range(w):
            if (grid[i][j].islower()):
                mark[ord(grid[i][j]) - 97].append((i, j))
            elif (grid[i][j] == 'S'):
                Sx, Sy = i, j
            elif (grid[i][j] == 'G'):
                Gx, Gy = i, j
    return Sx, Sy, Gx, Gy  # S、G的坐标


def bfs():
    bfs_que = deque()
    bfs_que.append((Sx, Sy))
    while bfs_que:
        x, y = bfs_que.popleft()#弹出队首的元素
        nxt_cost = cost[x][y] + 1
        for i in range(4):  # 循环四遍扫上下左右四个位置
            nxt_x = x + dx[i]
            nxt_y = y + dy[i]
            # 四个方位的位置信息
            if (nxt_x < 0 or nxt_y < 0 or nxt_x >= h or nxt_y >= w or grid[nxt_x][nxt_y] == '#'):#不符合要求的，出界的一律跳过
                continue
            if (cost[nxt_x][nxt_y] > nxt_cost):  # 需要入队的情况
                bfs_que.append((nxt_x, nxt_y))
                cost[nxt_x][nxt_y] = nxt_cost  # 更新最短的代价（时间成本）

        if (grid[x][y].islower()):#如果该位置是小写字母
            if (vis[ord(grid[x][y]) - 97] == 0):
                for other in mark[ord(grid[x][y]) - 97]:
                    other_x = other[0]
                    other_y = other[1]
                    if (cost[other_x][other_y] > nxt_cost):  # 需要更新的情况
                        cost[other_x][other_y] = nxt_cost  # 更新最短的代价（时间成本）
                        bfs_que.append((other_x, other_y))

            vis[ord(grid[x][y]) - 97] = 1

"""
《BFS+多传送门搜索》
根据bfs最短路的性质,先存下来每个字母的位置。然后bfs时当前字符为a~z时，看是否是第一次走过，如果是的话就对所有为相同字符的字母进行入队，
然后标记当前字母已经遍历过，否则直接跳过该操作，因为之后走到这个字母的步数一定大于第一次传送的步数，第一次传送必然是后面的传送中的最短的。
其他的操作就和普通的bfs一样，向4个方向遍历,不符合要求的，出界的一律跳过。

设置了一个vis数组来记录每个小写字母是否被遍历过
最后答案就在相应的位置坐标上。 ans = cost[Gx][Gy]
"""
if __name__ == '__main__':
    h, w = map(int, input().split())
    grid = [input() for i in range(h)]
    mark = [list() for i in range(26)]  # 一定要注意不能用[[]]*26，记录所有小写字母的所有位置
    Sx, Sy, Gx, Gy = markdown()  # S、G的坐标
    cost = [[INF] * w for i in range(h)]
    cost[Sx][Sy] = 0
    bfs()#调用
    ans = cost[Gx][Gy]
    if ans == INF:
        ans = -1
    print(ans)